﻿using Bilibili.Model.Common;
using Bilibili.Model.Resource;
using Bilibili.Model.Search;
using Bilibili.WebClient.Common;
using Newtonsoft.Json.Linq;
using PCLUntils.Json;
using System;
using System.Threading.Tasks;

namespace Bilibili.WebClient.Api
{
    public sealed class SearchClient : ClientBase
    {
        public async Task<ReturnModel<JObject>> GetLives(string keywords)
        {
            try
            {
                string url = $"https://api.bilibili.com/x/web-interface/search/type?search_type=live&platform=pc&keyword={keywords}&page=1";
                string results = await ApiClient.GetResultsWithUrl(url, ZipType.Normal);
                if (results.TryParseObject(out JObject jobj))
                    return BuildSuccessResult(jobj);
                else
                    return BuildFailedResult<JObject>();
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<JObject>(ex);
            }
        }
        public async Task<ReturnModel<JObject>> GetUser(string keywords, int index)
        {
            try
            {
                string url = $"https://api.bilibili.com/x/web-interface/search/type?search_type=live_user&platform=pc&keyword={keywords}&page={index}&order=online&coverType=user_cover";
                string results = await ApiClient.GetResultsWithUrl(url, ZipType.Normal);
                if (results.TryParseObject(out JObject jobj))
                    return BuildSuccessResult(jobj);
                else
                    return BuildFailedResult<JObject>();
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<JObject>(ex);
            }
        }
        public async Task<ReturnModel<JObject>> GetLiving(string keywords, int index)
        {
            try
            {
                string url = $"https://api.bilibili.com/x/web-interface/search/type?search_type=live&platform=pc&keyword={keywords}&page={index}";
                string results = await ApiClient.GetResultsWithUrl(url, ZipType.Normal);
                if (results.TryParseObject(out JObject jobj))
                    return BuildSuccessResult(jobj);
                else
                    return BuildFailedResult<JObject>();
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<JObject>(ex);
            }
        }
        public async Task<ApiDataModel<JObject>> GetLives(string condition, int pageNum)
        {
            try
            {
                var uri = $"https://api.bilibili.com/x/web-interface/search/type?context=&platform=pc&search_type=live&cover_type=user_cover&page={pageNum}&keyword={condition}&__refresh__=true&changing=mid&highlight=1&single_column=0";
                var results = await ApiClient.GetResultsWithUrl(uri, ZipType.Normal);
                if (results.TryParseObject(out ApiDataModel<JObject> data))
                    return data;
                else
                    return BuildApiFailedResult<JObject>();
            }
            catch (Exception ex)
            {
                return BuildApiExceptionResult<JObject>(ex);
            }
        }
        public async Task<ApiDataModel<JObject>> GetMovies(string condition, int pageNum)
        {
            try
            {
                var uri = $"https://api.bilibili.com/x/web-interface/search/type?context=&platform=pc&search_type=media_ft&page={pageNum}&order=&keyword={condition}&category_id=&__refresh__=true&highlight=1&single_column=0";
                var results = await ApiClient.GetResultsWithUrl(uri, ZipType.Normal);
                if (results.TryParseObject(out ApiDataModel<JObject> data))
                    return data;
                else
                    return BuildApiFailedResult<JObject>();
            }
            catch (Exception ex)
            {
                return BuildApiExceptionResult<JObject>(ex);
            }
        }
        public async Task<ApiDataModel<JObject>> GetBangmis(string condition, int pageNum)
        {
            try
            {
                var uri = $"https://api.bilibili.com/x/web-interface/search/type?context=&platform=pc&search_type=media_bangumi&page={pageNum}&order=&keyword={condition}&category_id=&__refresh__=true&highlight=1&single_column=0";
                string results = await ApiClient.GetResultsWithUrl(uri, ZipType.Normal);
                if (results.TryParseObject(out ApiDataModel<JObject> data))
                    return data;
                else
                    return BuildApiFailedResult<JObject>();
            }
            catch (Exception ex)
            {
                return BuildApiExceptionResult<JObject>(ex);
            }
        }
        public async Task<ApiDataModel<JObject>> GetActivities(string condition, int pageNum)
        {
            try
            {
                var uri = $"https://api.bilibili.com/x/web-interface/search/type?context=&platform=pc&search_type=topic&page={pageNum}&order=&keyword={condition}&category_id=&__refresh__=true&highlight=1&single_column=0";
                var results = await ApiClient.GetResultsWithUrl(uri, ZipType.Normal);
                if (results.TryParseObject(out ApiDataModel<JObject> data))
                    return data;
                else
                    return BuildApiFailedResult<JObject>();
            }
            catch (Exception ex)
            {
                return BuildApiExceptionResult<JObject>(ex);
            }
        }
        public async Task<ApiDataModel<JObject>> GetUsers(string condition, string order, string type, int pageNum)
        {
            try
            {
                var uri = $"https://api.bilibili.com/x/web-interface/search/type?context=&platform=pc&search_type=bili_user&page={pageNum}&keyword={condition}{order}{type}&__refresh__=true&changing=mid&highlight=1&single_column=0&category_id=";
                var results = await ApiClient.GetResultsWithUrl(uri, ZipType.Normal);
                if (results.TryParseObject(out ApiDataModel<JObject> data))
                    return data;
                else
                    return BuildApiFailedResult<JObject>();
            }
            catch (Exception ex)
            {
                return BuildApiExceptionResult<JObject>(ex);
            }
        }
        public async Task<ApiDataModel<JObject>> GetArticles(string condition, string order, string region, int pageNum)
        {
            try
            {
                var uri = $"https://api.bilibili.com/x/web-interface/search/type?context=&platform=pc&search_type=article&page={pageNum}&order={order}&keyword={condition}&category_id={region}&__refresh__=true&highlight=1&single_column=0";
                string results = await ApiClient.GetResultsWithUrl(uri, ZipType.Normal);
                if (results.TryParseObject(out ApiDataModel<JObject> data))
                    return data;
                else
                    return BuildApiFailedResult<JObject>();
            }
            catch (Exception ex)
            {
                return BuildApiExceptionResult<JObject>(ex);
            }
        }
        public async Task<ReturnModel<SearchVideoItem>> GetVideos(string condition, int page, string areaCondition, string typeCondition)
        {
            try
            {
                var uri = $"https://api.bilibili.com/search?_device=android&{ApiProvider.Instance.AndroidKeySign}&keyword={condition}&main_ver=v3&page={page}&pagesize=20&platform=android&search_type=video&source_type=0{areaCondition}{typeCondition}";
                var results = await ApiClient.GetResultsWithUrl(uri, ZipType.Normal);
                var model = results.ParseObject<SearchVideoItem>();
                return BuildSuccessResult(model);
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<SearchVideoItem>(ex);
            }
        }
    }
}